import { message } from '@tauri-apps/api/dialog';
import { useControllableValue, useMemoizedFn } from 'ahooks';
import { Typography } from 'antd';
import { FormInstance } from 'rc-field-form';
import React, { useEffect, useState } from 'react';
import EditableTable from '../EditableTable';

interface CommondInputProps {
  value?: CommandItem[];
  onChange?: (val: CommandItem[]) => void;
}

const defaultKey = '#@000@#';

function getNewRow() {
  return { label: '', value: '', command: '', key: defaultKey };
}

export function checkRow(row: CommandItem, mList: CommandItem[]) {
  const { label, value, command } = row;
  if (!label || !value || !command) {
    return '请完善命令信息';
  }
  // 校验显示名是否有重复
  if (mList.length !== new Set(mList.map(({ label }) => label)).size) {
    return '显示名重复，请检查';
  }
  // 校验代码是否有重复
  if (mList.length !== new Set(mList.map(({ value }) => value)).size) {
    return '命令代码重复，请检查';
  }
  return null;
}

const CommandInput: React.FC<CommondInputProps> = (props) => {
  const [state, setState] = useControllableValue<CommandItem[]>(props);
  const isEditing = (record: any) => record.key === editingKey;

  const [form, setForm] = useState<FormInstance<any>>();
  const [editingKey, setEditingKey] = useState<string | undefined>(undefined);

  //编辑行
  const edit = (record: Partial<CommandItem>) => {
    form?.setFieldsValue(record);
    setEditingKey(record.key);
  };
  // 取消编辑
  const cancel = useMemoizedFn(async (key?: string) => {
    if (key === defaultKey) {
      const newData = [...state];
      const index = newData.findIndex((item) => key === item.key);
      if (index > -1) {
        newData.splice(index, 1);
      }
      setState(newData);
    }
    setEditingKey(undefined);
  });

  // 保存编辑
  const save = async (key?: string) => {
    try {
      const row = (await form?.validateFields()) as CommandItem;
      row.key = row.value;
      const newData = [...state];
      const index = newData.findIndex((item) => key === item.key);
      const item = newData[index];
      if (index > -1) {
        newData.splice(index, 1, {
          ...item,
          ...row,
        });
      } else {
        newData.push(row);
      }
      // 校验数据是否完整
      const errMsg = checkRow(row, newData);
      if (errMsg) {
        await message(errMsg, {
          title: '提示',
          type: 'error',
        });
        return;
      }
      setState(newData);
      setEditingKey(undefined);
    } catch (errInfo) {
      console.log('Validate Failed:', errInfo);
    }
  };
  // 添加行
  const addRow = (key?: string) => {
    form?.resetFields();
    const newData = [...state];
    const index = newData.findIndex((item) => key === item.key);
    const newRow = getNewRow();
    if (index > -1) {
      newData.splice(index + 1, 0, newRow);
    } else {
      newData.push(newRow);
    }
    setState(newData);
    setEditingKey(newRow.key);
  };

  // 删除行
  const delRow = (key?: string) => {
    const newData = [...state];
    const index = newData.findIndex((item) => key === item.key);
    if (index > -1) {
      newData.splice(index, 1);
    }
    setState(newData);
    if (key === editingKey) {
      setEditingKey(undefined);
    }
  };

  const columns: any[] = [
    {
      dataIndex: 'label',
      title: '显示名',
      editable: true,
      width: 120,
      disabled: (row: CommandItem) => row.fixed,
    },
    {
      dataIndex: 'value',
      title: '代码',
      editable: true,
      width: 120,
      disabled: (row: CommandItem) => row.fixed,
    },
    {
      dataIndex: 'command',
      title: '命令',
      editable: true,
      width: 120,
    },
    {
      dataIndex: 'action',
      title: '操作',
      width: 130,
      render: (_: any, record: CommandItem) => {
        const editable = isEditing(record);
        return (
          <>
            {editable ? (
              <span>
                <Typography.Link
                  onClick={() => save(record.key)}
                  style={{ marginRight: 8 }}
                >
                  保存
                </Typography.Link>
                <Typography.Link
                  style={{ marginRight: 8 }}
                  onClick={() => cancel(record.key)}
                >
                  取消
                </Typography.Link>
              </span>
            ) : (
              <span>
                <Typography.Link
                  disabled={!!editingKey}
                  onClick={() => edit(record)}
                  style={{ marginRight: 8 }}
                >
                  编辑
                </Typography.Link>
                <Typography.Link
                  disabled={!!editingKey}
                  onClick={() => addRow(record.key)}
                  style={{ marginRight: 8 }}
                >
                  新增
                </Typography.Link>
              </span>
            )}
            {!record.fixed && (
              <Typography.Link onClick={() => delRow(record.key)}>
                删除
              </Typography.Link>
            )}
          </>
        );
      },
    },
  ];

  return (
    <div className="command-input">
      <EditableTable
        editingKey={editingKey}
        dataSource={state}
        columns={columns}
        onLoad={setForm}
      />
    </div>
  );
};

export default React.memo(CommandInput);
